﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Artemis;

namespace JAWWS
{
    class Player : Actor
    {
        private LinkedList<Item> inventory;
        private Weapon currentWeapon;
        private HPItem hpItem;
        private HPItem hpItem2;
        public NoWeapon noWeapon;
        public HandGun handgun;
        public Rifle rifle;
        public Knife knife;
        private ItemName iname;
        private float attackRange;

        public Player(MainForm main)
        {
            Position[0] = logic.getStartingPos()[0];
            Position[1] = logic.getStartingPos()[1];
            Position[2] = logic.getStartingPos()[2];
            this.Health = logic.getTotalHealth();
            this.inventory = new LinkedList<Item>();
            this.Strength = logic.getBaseStr();
            this.Accuracy = logic.getBaseAcc();
            this.Speed = logic.getBaseSpeed();
            this.Alive = true;
            noWeapon = new NoWeapon();
            handgun = new HandGun();
            currentWeapon = handgun;
            rifle = new Rifle();
            knife = new Knife();
            hpItem = new HPItem(main, Position);
            hpItem.setInInventory(true);
            hpItem2 = new HPItem(main, Position);
            hpItem2.setInInventory(true);
            addItemToInventory(hpItem);
            addItemToInventory(hpItem2);
            attackRange = 2.0f;
        }
        public void addItemToInventory(Item item)
        {
            //Adds a new Item to the inventory
            LinkedListNode<Item> itemNode = new LinkedListNode<Item>(item);
            if (inventory.Count >= logic.getTotalPlayerInventory())
            {
                //throw some kind of error/print msg
            }
            else
            {
                inventory.AddLast(itemNode);
            }
        }

        public void addToInventory(ItemName weaponType)
        {
            if (weaponType == ItemName.HANDGUN)
            {
                // arsenal[1] = handgun;
                this.inventory.AddLast(handgun);
            }
            else if (weaponType == ItemName.RIFLE)
            {
                //arsenal[2] = rifle;
                this.inventory.AddLast(rifle);
            }
            else if (weaponType == ItemName.KNIFE)
            {
                //arsenal[3] = knife;
                this.inventory.AddLast(knife);
            }
            else if (weaponType == ItemName.NO_WEAPON)
            {
                this.inventory.AddLast(noWeapon);
            }
            this.iname = weaponType;
        }
        public ItemName getWeaponType()
        {
            return this.iname;
        }

        public Weapon getCurrentWeapon()
        {
            return currentWeapon;
        }
        public void useItem(ItemName name)
        {
            // If the item is an HPItem type.
            if (name == ItemName.HP_ITEM)
            {
                for (int i = 0; i < inventory.Count; i++)
                {
                    if (inventory.ElementAt(i) != null)
                    {
                        // If an HPItem is in our inventory.
                        if (inventory.ElementAt(i).getType() == ItemName.HP_ITEM)
                        {
                            // Adds the HPItem's health bonus to the player and removes item
                            inventory.ElementAt(i).apply(this);
                            Item removedItem = inventory.ElementAt(i);
                            inventory.Remove(removedItem);
                        }
                    }
                }
            }
            //If item is an Ammo Pack
            else if (name == ItemName.AMMO_PACK)
            {
                for (int i = 0; i < inventory.Count; i++)
                {
                    if (inventory.ElementAt(i) != null)
                    {
                        //If an Ammo Pack is in the inventory
                        if (inventory.ElementAt(i).getType() == ItemName.AMMO_PACK)
                        {
                            //Add the Ammo to the current weapon and remove from inventory
                            inventory.ElementAt(i).apply(this);
                            Item removedItem = inventory.ElementAt(i);
                            inventory.Remove(removedItem);
                        }
                    }
                }
            }
        }
        public void switchWeapon(ItemName weaponType)
        {
            if (weaponType == ItemName.NO_WEAPON)
            {
                //currentWeapon = arsenal[0];
                if (this.inventory.Contains(noWeapon))
                {
                    currentWeapon = (Weapon)this.inventory.Find(noWeapon).Value;
                }
            }
            else if (weaponType == ItemName.HANDGUN)
            {
                //currentWeapon = arsenal[1];
                if (this.inventory.Contains(handgun))
                {
                    currentWeapon = (Weapon)this.inventory.Find(handgun).Value;
                }
            }
            else if (weaponType == ItemName.RIFLE)
            {
                //currentWeapon = arsenal[2];
                if (this.inventory.Contains(rifle))
                {
                    currentWeapon = (Weapon)this.inventory.Find(rifle).Value;
                }
            }
            else if (weaponType == ItemName.KNIFE)
            {
                //currentWeapon = arsenal[3];
                if (this.inventory.Contains(knife))
                {
                    currentWeapon = (Weapon)this.inventory.Find(knife).Value;
                }
            }
        }
        public override void attack(Actor enemy, Projectile proj)
        {
            //If the player is within range, alive, and in sight, attack with weapon.
            if (enemy.getAlive() == true && Alive == true)
            {
                float deltax = (enemy.getPosition()[0] - proj.getPos()[0]);
                float deltaz = (enemy.getPosition()[2] - proj.getPos()[2]);
                float deltay = (enemy.getPosition()[1] - proj.getPos()[1]);
                //float len = (float) Math.Sqrt((double) (deltax*deltax + deltaz*deltaz + deltay*deltay)) ;

                float len = (float)Math.Sqrt((double)deltax * deltax + deltaz * deltaz);
                
                //Will be able to hit if within range.
                if (len < attackRange && proj.getPos()[1] >= enemy.getPosition()[1] && proj.getPos()[1] < 10.0f)
                {

                    //Does extra dammage depending on where the actor is hit.
                    int hitPlace = rand.Next(100);
                    if (hitPlace >= 0 && hitPlace <= 10)
                    {
                        //Head Shot
                        enemy.adjustHealth(-(currentWeapon.getBaseDammage() * Strength + 10));
                        proj.fired = false;
                    }
                    else if (hitPlace >= 11 && hitPlace <= 35)
                    {
                        //Chest Shot 
                        enemy.adjustHealth(-(currentWeapon.getBaseDammage() * Strength + 5));
                        proj.fired = false;
                    }
                    else if (hitPlace >= 36 && hitPlace <= 75)
                    {
                        //Arms Shot - will lessen the acc. of the actor.
                        enemy.adjustHealth(-(currentWeapon.getBaseDammage() * Strength));
                        enemy.setAcc(-1);
                        proj.fired = false;
                    }
                    else
                    {
                        //Legs Shot - will lessen the speed of the actor.
                        enemy.adjustHealth(-(currentWeapon.getBaseDammage() * Strength));
                        if (enemy.getSpeed() > 0)
                        {
                            enemy.setSpeed(-0.01f);
                        }
                        proj.fired = false;
                    }
                }
            }
        }
        public override void attack(Actor actor)
        {
            //Does nothing
        }
        public override void draw()
        {
            
        }
    }
}
